<div class="neo-header-text-container">
    <span class="neo-header-text">Tutorial: Remote Method Access</span>
</div>
<article>
    <p>To simplify the communication between the different workers (App, Data, VDom),
        neoteric provides remote method access for singletons.
        As an example, let's take a look at the vdom.Helper which lives inside the VDom worker:</p>
    <pre><code>class Helper extends Base {
    static getConfig() {return {
        className: 'Neo.vdom.Helper',
        ntype    : 'vdom-helper',
        singleton: true,

        remote: {
            app: ['create', 'update']
        }
        //...
    }

    create(opts) {
        //...
    }

    update(opts) {
        //...
    }

    //...
}</code></pre>
    <p>As you can see, you can use the remote config to define method names (string based)
        for other worker targets (lower case => app, data, vdom).
        Using the remote config will automatically create the matching namespaces inside the target workers.
        The remotely defined methods can then get called as a promise.
        Example inside the App worker (component.Base):
    </p>
    <pre><code>updateVdom(vdom, vnode) {
    let me = this;

    Neo.vdom.Helper.update({
        vdom : vdom,
        vnode: vnode
    }).then(data => {
        Object.keys(me.vnode).forEach(key => {
            delete me.vnode[key];
        });

        Object.assign(me.vnode, data.vnode);

        me.syncVdomIds(me.vnode, me.vdom);
    }).catch(err => {
        console.log('Error attempting to update component dom', err, me);
    });
}</code></pre>
    <p>Obviously, using a remote method works asynchronously. What happens under the hood is that the app worker
        will send a postMessage to the main thread, main a postMessage to the VDom worker,
        vdom will send back the response to main and main forward this to app.
        We can reduce the routes once SharedWorkers are supported.</p>
    <p>You can directly promise messages to a target worker or the main thread as well.
        As an example: component.Base: updateStyle()</p>
    <pre><code>updateStyle(newValue, oldValue) {
    let delta = Style.compareStyles(newValue, oldValue);

    if (delta) {
        Neo.currentWorker.promiseMessage('main', {
            action: 'updateDom',
            deltas: [
                {
                    id   : this.id,
                    style: delta
                }
            ]
        }).then(() => {
            console.log('Component style updated');
        }).catch(err => {
            console.log('Error attempting to update component style', err, this);
        });
    }
}</code></pre>
    <p>This allows you to send messages directly to the main thread or to a different worker.
        In case the target is not main, neoteric will send the message to main and from there to the target worker
        and afterwards forward the reply back to the origin.</p>
</article>